
#include "tfilesearcher.h"
#include <windows.h>
LIB_NS_BEGIN
	//////////////////////////////////////////////////////////////////////
	// Construction/Destruction
	//////////////////////////////////////////////////////////////////////
	
	TFileSearcher::TFileSearcher()
		: _limit(def_limit), _dirs(0)
	{
		
	}
	
	TFileSearcher::~TFileSearcher()
	{
		
	}
	
	//////////////////////////////////////////////////////////////////////
	tstring TFileSearcher::_uppercase_(tstring s)
	{
		const char aazz = 'z' - 'Z';
		tstring rs;
		for (tstring::iterator it = s.begin();
		s.end() != it; it++)
		{
			if ('a' <= *it && *it <= 'z') rs.append(1, *it - aazz);
			else rs.append(1, *it);
		}
		return rs;
	}
	//////////////////////////////////////////////////////////////////////
	
	int TFileSearcher::match(tstring fext_, tstring file_)
	{
		tstring fext = _uppercase_(fext_);
		tstring file = _uppercase_(file_);
		
		int pos = file.find_last_of('.');
		if (tstring::npos != pos) file = file.substr(pos);
		
		return (tstring::npos != fext.find(file));
	}
	
	void TFileSearcher::limit(int limit_)
	{
		if (limit_ < 1) _limit = def_limit;
		if (limit_ < max_limit) _limit = limit_;
	}
	
	int TFileSearcher::dir(tstring s)
	{
		return (FILE_ATTRIBUTE_DIRECTORY == GetFileAttributes(s.c_str()));
	}
	
	int TFileSearcher::find(tstring path_, tstring fext_)
	{
		_co_file.clear();
		_co_dir.clear();
		_co.clear();
		
		tstring path = path_;
		if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
			path.append(s_pathSeparator);
		
		_co_dir.push_back( path );
		
		tstring fext = fext_;
		if (0 == fext.compare(_T("*"))
			|| 0 == fext.compare(_T("*.*"))
			) fext = _T("");

		//tstring file = fext;
		tstring file = _T("*");
		
		tstring s = path + file;
		
		WIN32_FIND_DATA fileinfo = {0};
		HANDLE handle = FindFirstFile( s.c_str(), &fileinfo );
		
		if (NULL != handle && INVALID_HANDLE_VALUE != handle)
		{
			
			do {
				
				if (_limit_()) break;	//--limit test
				
				if (_T('.') != fileinfo.cFileName[0])	//--skip./..
					if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes)
						== FILE_ATTRIBUTE_DIRECTORY)	//--Ŀ¼
					{
						if (!_limit_()	//--limit test
							//&& 0 == fext.size()
							) _co_dir.push_back( path + fileinfo.cFileName + s_pathSeparator );
						
						if (0 != dirs())
						{
							TFileSearcher o;
							o.dirs(dirs());
							o.find( path + fileinfo.cFileName, fext);
							//--dir
							typeT o_dir = o.co_dir();
							for (typeT::iterator it_dir = o_dir.begin();
							o_dir.end() != it_dir && !_limit_();	//--limit test
							it_dir ++) _co_dir.push_back(*it_dir);
							//--file
							typeT o_file = o.co_file();
							for (typeT::iterator it_file = o_file.begin();
							o_file.end() != it_file && !_limit_();	//--limit test
							it_file ++) _co_file.push_back(*it_file);
						}
					}
					else
					{
						if (!_limit_()	//--limit test
							&& (0 == fext.size() || match(fext, fileinfo.cFileName))
							) _co_file.push_back( path + fileinfo.cFileName );
					}
					
			} while (FindNextFile( handle, &fileinfo ));
			
			FindClose(handle);
		}
		
		//--dir
		for (typeT::iterator it_dir = _co_dir.begin();
		_co_dir.end() != it_dir;
		it_dir ++) _co.push_back(*it_dir);
		//--file
		for (typeT::iterator it_file = _co_file.begin();
		_co_file.end() != it_file;
		it_file ++) _co.push_back(*it_file);
		
		return count();
	}
	
	LIB_NS_END